package top.lishuoboy.springmvc.a3;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/a3")
@Slf4j
public class RequestMappingTest {

    /**
     * "@RequestMapping"注解的位置
     * “@RequestMapping“标识一个类：设置映射请求的请求路径的初始信息
     * ”@RequestMapping”标识一个方法：设置映射请求请求路径的具体信息
     * 此时请求映射所映射的请求的请求路径为：/a3/1
     *
     * @return
     */
    @RequestMapping("/1")
    private String requestMappingLocation() {
        return "public";
    }


    /**
     * 3、@RequestMapping注解的value属性
     * "@RequestMapping"注解的value属性通过请求的请求地址匹配请求映射
     * "@RequestMapping"注解的value属性是一个字符串类型的数组，表示该请求映射能够匹配多个请求地址所对应的请求
     * "@RequestMapping"注解的value属性必须设置，至少通过请求地址匹配请求映射
     *
     * @return
     */
    @RequestMapping(value = {"/2", "/2_2"})
    private String requestMappingValue() {
        return "public";
    }


    /**
     * 4、"@RequestMapping"注解的method属性
     * "@RequestMapping"注解的method属性通过请求的请求方式（get或post等）匹配请求映射
     * "@RequestMapping"注解的method属性是一个RequestMethod类型的数组，表示该请求映射能够匹配多种请求方式的请求
     * 若当前请求的请求地址满足请求映射的value属性，但是请求方式不满足method属性，则浏览器报错
     * 405：Request method 'POST' not supported
     * <p>
     * 注：
     * 1、对于处理指定请求方式的控制器方法，SpringMVC中提供了@RequestMapping的派生注解
     * 处理get请求的映射-->@GetMapping
     * 处理post请求的映射-->@PostMapping
     * 处理put请求的映射-->@PutMapping
     * 处理delete请求的映射-->@DeleteMapping
     * 2、常用的请求方式有get，post，put，delete
     * 但是目前浏览器只支持get和post，若在form表单提交时，为method设置了其他请求方式的字符串（put或delete），则按照默认的请求方式get处理
     * 若要发送put和delete请求，则需要通过spring提供的过滤器HiddenHttpMethodFilter，在
     * RESTful部分会讲到
     */
    @RequestMapping(value = "/4", method = RequestMethod.GET)
//    @RequestMapping(value = "/4", method = {RequestMethodPPOST,RequestMethod.DELETE})
//    @GetMapping("/4")
//    @PostMapping("/4")
//    @PutMapping("/4")
//    @DeleteMapping("/4")
    public String requestMappingMethod() {
        log.info("requestMappingMethod");
        return "a3/4";
    }


    /**
     * 5、"@RequestMapping"注解的params属性（了解）
     * "@RequestMapping"注解的params属性通过请求的请求参数匹配请求映射
     * "@RequestMapping"注解的params属性是一个字符串类型的数组，可以通过四种表达式设置请求参数和请求映射的匹配关系
     * "param"：要求请求映射所匹配的请求必须携带param请求参数
     * "!param"：要求请求映射所匹配的请求必须不能携带param请求参数
     * "param=value"：要求请求映射所匹配的请求必须携带param请求参数且param=value
     * "param!=value"：要求请求映射所匹配的请求必须携带param请求参数但是param!=value
     * <p>
     * 注：
     * 若当前请求满足@RequestMapping注解的value和method属性，但是不满足params属性，此时页面回报错400：Parameter conditions "username, password!=123456" not met for actual
     */
    // name 必须有name属性，且不能有name2属性，且有pwd属性 值为123，且有pwd2属性 值不能是123
    // http://localhost:8080/lishuoboy_springmvc_war_exploded/a3/5?name&pwd=111&pwd2=1111
    @RequestMapping(value = "/5", params = {"name", "!name2", "pwd=111", "pwd2!=111"})
    public String requestMappingParam() {
        log.info("requestMappingParam");
        return "public";
    }

    /**
     * 6、"@RequestMapping"注解的headers属性（了解） ，未测试，同上面的params
     * "@RequestMapping"注解的headers属性通过请求的请求头信息匹配请求映射
     * "@RequestMapping"注解的headers属性是一个字符串类型的数组，可以通过四种表达式设置请求头信息和请求映射的匹配关系
     * "header"：要求请求映射所匹配的请求必须携带header请求头信息
     * "!header"：要求请求映射所匹配的请求必须不能携带header请求头信息
     * "header=value"：要求请求映射所匹配的请求必须携带header请求头信息且header=value
     * "header!=value"：要求请求映射所匹配的请求必须携带header请求头信息且header!=value
     * 若当前请求满足@RequestMapping注解的value和method属性，但是不满足headers属性，此时页面
     * 显示404错误，即资源未找到
     *
     * @return
     */
    @RequestMapping(value = "/6", headers = {"name", "!name2"})
    public String requestMappingHeaders() {
        log.info("requestMappingHeaders");
        return "public";
    }

    /**
     * 7、SpringMVC支持ant风格的路径
     * <a th:href="@{/test(username='admin',password=123456)">测试@RequestMapping的 params属性-->/test</a><br> @RequestMapping( value = {"/testRequestMapping", "/test"} ,method = {RequestMethod.GET, RequestMethod.POST} ,params = {"username","password!=123456"} )public String testRequestMapping(){ return "success"; }
     * 更多Java –大数据 – 前端 – UI/UE - Android - 人工智能资料下载，可访问百度：尚硅谷官网(www.atguigu.com)
     * ？：表示任意的单个字符
     * *：表示任意的0个或多个字符
     * **：表示任意的一层或多层目录
     * 注意：在使用**时，只能使用  /** / xxx的方式
     */
    // http://localhost:8080/lishuoboy_springmvc_war_exploded/a3/7/
    @RequestMapping(value = "/7/*")
    public String requestMappingAnt() {
        log.info("requestMappingAnt");
        return "public";
    }

    /**
     * 8、SpringMVC支持路径中的占位符（重点）
     * 原始方式：/deleteUser?id=1
     * rest方式：/deleteUser/1
     * SpringMVC路径中的占位符常用于RESTful风格中，当请求路径中将某些数据通过路径的方式传输到服务器中，就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据，再通过@PathVariable注解，将占位符所表示的数据赋值给控制器方法的形参
     * get乱码需要配置tomcat server.xml  URIEncoding="UTF-8"。 post乱码和restful乱码需要配置过滤器
     * 更准确的说法get或post的url ?后面的参数需要配置tomcat server.xml  URIEncoding="UTF-8"。post请求体或restful的参数需要在web.xml中配置CharacterEncodingFilter
     * request.setCharacterEncoding("");一旦设置执行过，后面再次执行都无效，所以过滤器再之前已经执行过，当前方法内执行也没用
     */
    // http://localhost:8080/lishuoboy_springmvc_war_exploded/a3/8/100/张三
    @RequestMapping(value = "/8/{id}/{name}")
    public String requestMappingRestful(@PathVariable("name") String name, @PathVariable("id") int id) {
        log.info("requestMappingRestful");
        log.warn("id=={},name={}", id, name);
        return "public";
    }


}
